import { MD5 } from '@/utils/md5'
import { CATEGORIES_STORE, URLS_STORE, UI_SETTINGS_STORE, DB_NAME, DB_VERSION } from '@/enum';
// IndexedDB 存储服务
// 深度克隆对象，移除不可克隆的属性
const sanitizeForStorage = (obj, seen = new WeakMap()) => {
  // 处理 null 或 undefined
  if (obj === null || obj === undefined) {
    return obj;
  }

  // 处理基本类型
  if (typeof obj !== 'object') {
    return obj;
  }

  // 检测循环引用
  if (seen.has(obj)) {
    console.warn('Circular reference detected, returning empty object');
    return {};
  }

  // 记录当前对象，防止循环引用
  seen.set(obj, true);

  // 处理日期
  if (obj instanceof Date) {
    return new Date(obj);
  }

  // 处理正则表达式
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }

  // 处理数组
  if (Array.isArray(obj)) {
    try {
      return obj.map(item => sanitizeForStorage(item, seen));
    } catch (e) {
      console.error('Error sanitizing array item:', e);
      return [];
    }
  }

  // 处理普通对象
  try {
    const result = {};
    for (const [key, value] of Object.entries(obj)) {
      // 跳过函数、Symbol等不可克隆的类型
      if (typeof value === 'function' || typeof value === 'symbol') {
        continue;
      }

      // 处理值
      try {
        if (value !== null && typeof value === 'object') {
          result[key] = sanitizeForStorage(value, seen);
        } else {
          result[key] = value;
        }
      } catch (e) {
        console.warn(`Cannot sanitize property ${key}, skipping:`, e);
      }
    }
    return result;
  } catch (e) {
    console.error('Error sanitizing object:', e);
    return {};
  }
};

// 初始化数据库
const initDB = () => {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, DB_VERSION);

    request.onerror = (event) => {
      console.error('IndexedDB error:', event.target.error);
      reject(event.target.error);
    };

    request.onsuccess = (event) => {
      const db = event.target.result;
      resolve(db);
    };

    request.onupgradeneeded = (event) => {
      const db = event.target.result;

      // 创建分类存储
      if (!db.objectStoreNames.contains(CATEGORIES_STORE)) {
        const categoriesStore = db.createObjectStore(CATEGORIES_STORE, { keyPath: 'id' });
        categoriesStore.createIndex('name', 'name', { unique: false });
      }

      // 创建URL存储
      if (!db.objectStoreNames.contains(URLS_STORE)) {
        const urlsStore = db.createObjectStore(URLS_STORE, { keyPath: 'id' });
        urlsStore.createIndex('categoryId', 'categoryId', { unique: false });
        urlsStore.createIndex('title', 'title', { unique: false });
        urlsStore.createIndex('url', 'url', { unique: false });
      }

      // 创建UI设置存储
      if (!db.objectStoreNames.contains(UI_SETTINGS_STORE)) {
        db.createObjectStore(UI_SETTINGS_STORE, { keyPath: 'id' });
      }
    };
  });
};

// 获取数据库连接
const getDB = async () => {
  try {
    return await initDB();
  } catch (error) {
    console.error('Failed to get database connection:', error);
    throw error;
  }
};

// 存储服务
export const storage = {
  // 获取数据
  get: async function (keys, callback) {
    try {
      console.log('Getting data for keys:', keys);
      const db = await getDB();
      const result = {};

      // 处理每个请求的键
      for (const key of keys) {
        // 检查对象存储是否存在
        if (!db.objectStoreNames.contains(key)) {
          console.warn(`Object store "${key}" does not exist in the database`);
          result[key] = [];
          continue;
        }

        if (key === CATEGORIES_STORE) {
          const transaction = db.transaction([CATEGORIES_STORE], 'readonly');
          const store = transaction.objectStore(CATEGORIES_STORE);
          const request = store.getAll();

          await new Promise((resolve, reject) => {
            request.onsuccess = (event) => {
              result[key] = event.target.result;
              console.log(`Retrieved ${result[key].length} categories`);
              resolve();
            };

            request.onerror = (event) => {
              console.error('Error getting categories:', event.target.error);
              reject(event.target.error);
            };
          });
        } else if (key === URLS_STORE) {
          const transaction = db.transaction([URLS_STORE], 'readonly');
          const store = transaction.objectStore(URLS_STORE);
          const request = store.getAll();

          await new Promise((resolve, reject) => {
            request.onsuccess = (event) => {
              result[key] = event.target.result;
              console.log(`Retrieved ${result[key].length} URLs`);
              resolve();
            };

            request.onerror = (event) => {
              console.error('Error getting URLs:', event.target.error);
              reject(event.target.error);
            };
          });
        } else if (key === UI_SETTINGS_STORE) {
          const transaction = db.transaction([UI_SETTINGS_STORE], 'readonly');
          const store = transaction.objectStore(UI_SETTINGS_STORE);
          const request = store.get('settings');

          await new Promise((resolve, reject) => {
            request.onsuccess = (event) => {
              result[key] = event.target.result ? event.target.result.data : null;
              console.log('Retrieved UI settings:', result[key]);
              resolve();
            };

            request.onerror = (event) => {
              console.error('Error getting UI settings:', event.target.error);
              reject(event.target.error);
            };
          });
        }
      }

      // 调用回调函数返回结果
      console.log('Returning result:', result);
      callback(result);
    } catch (error) {
      console.error('Error in get operation:', error);
      callback({});
    }
  },

  // 设置数据
  set: async function (data) {
    try {
      console.log('Setting data:', data);
      const db = await getDB();

      // 处理每个数据键
      for (const [key, value] of Object.entries(data)) {
        // 检查对象存储是否存在
        if (!db.objectStoreNames.contains(key)) {
          console.warn(`Object store "${key}" does not exist in the database`);
          continue;
        }

        if (key === CATEGORIES_STORE && Array.isArray(value)) {
          try {
            // 清除现有数据
            await new Promise((resolve, reject) => {
              const clearTx = db.transaction([CATEGORIES_STORE], 'readwrite');
              const clearStore = clearTx.objectStore(CATEGORIES_STORE);
              const clearRequest = clearStore.clear();

              clearRequest.onsuccess = () => {
                console.log('Successfully cleared categories');
                resolve();
              };

              clearRequest.onerror = (event) => {
                console.error('Error clearing categories:', event.target.error);
                reject(event.target.error);
              };

              clearTx.oncomplete = () => {
                console.log('Clear transaction complete');
              };

              clearTx.onerror = (event) => {
                console.error('Clear transaction error:', event.target.error);
              };
            });

            // 逐个添加数据，每个对象创建一个单独的事务
            for (const category of value) {
              // 净化对象，移除不可克隆的属性
              const sanitizedCategory = sanitizeForStorage(category);
              await new Promise((resolve, reject) => {
                const addTx = db.transaction([CATEGORIES_STORE], 'readwrite');
                const addStore = addTx.objectStore(CATEGORIES_STORE);
                const addRequest = addStore.add(sanitizedCategory);

                addRequest.onsuccess = () => {
                  resolve();
                };

                addRequest.onerror = (event) => {
                  console.error('Error adding category:', event.target.error, sanitizedCategory);
                  // 即使单个添加失败，也允许继续
                  resolve();
                };

                addTx.oncomplete = () => {
                  // 事务完成
                };

                addTx.onerror = (event) => {
                  console.error('Add transaction error:', event.target.error);
                };
              });
            }

            console.log(`Successfully saved ${value.length} categories`);
          } catch (err) {
            console.error('Error in categories save operation:', err);
          }
        } else if (key === URLS_STORE && Array.isArray(value)) {
          try {
            // 清除现有数据
            await new Promise((resolve, reject) => {
              const clearTx = db.transaction([URLS_STORE], 'readwrite');
              const clearStore = clearTx.objectStore(URLS_STORE);
              const clearRequest = clearStore.clear();

              clearRequest.onsuccess = () => {
                console.log('Successfully cleared URLs');
                resolve();
              };

              clearRequest.onerror = (event) => {
                console.error('Error clearing URLs:', event.target.error);
                reject(event.target.error);
              };
            });

            // 逐个添加数据，每个对象创建一个单独的事务
            for (const url of value) {
              // 净化对象，移除不可克隆的属性
              const sanitizedUrl = sanitizeForStorage(url);

              await new Promise((resolve, reject) => {
                const addTx = db.transaction([URLS_STORE], 'readwrite');
                const addStore = addTx.objectStore(URLS_STORE);
                const addRequest = addStore.add(sanitizedUrl);

                addRequest.onsuccess = () => {
                  resolve();
                };

                addRequest.onerror = (event) => {
                  console.error('Error adding URL:', event.target.error, sanitizedUrl);
                  // 即使单个添加失败，也允许继续
                  resolve();
                };
              });
            }

            console.log(`Successfully saved ${value.length} URLs`);
          } catch (err) {
            console.error('Error in URLs save operation:', err);
          }
        } else if (key === UI_SETTINGS_STORE) {
          try {
            const transaction = db.transaction([UI_SETTINGS_STORE], 'readwrite');
            const store = transaction.objectStore(UI_SETTINGS_STORE);
            // 保存 UI 设置
            const settingsData = {
              id: 'settings',
              data: sanitizeForStorage(value)
            };
            await new Promise((resolve, reject) => {
              const request = store.put(settingsData);
              request.onsuccess = () => {
                console.log('Successfully saved UI settings');
                resolve();
              };
              request.onerror = (event) => {
                console.error('Error saving UI settings:', event.target.error);
                reject(event.target.error);
              };
            });
          } catch (err) {
            console.error('Error in UI settings save operation:', err);
          }
        }
      }

      return true;
    } catch (error) {
      console.error('Error in set operation:', error);
      return false;
    }
  }
};

// 初始化默认数据
export const initializeDefaultData = async () => {
  try {
    console.log('Initializing default data...');
    // 检查是否已有数据
    return new Promise((resolve, reject) => {
      storage.get([CATEGORIES_STORE, URLS_STORE], async (result) => {
        try {
          console.log('Checking existing data:', result);

          if (!result[CATEGORIES_STORE] || result[CATEGORIES_STORE].length === 0) {
            console.log('No categories found, creating default categories');
            // 设置默认分类
            const defaultData = {
              [CATEGORIES_STORE]: [
                { id: MD5('默认分类'), name: '默认分类' }
              ],
              [URLS_STORE]: []
            };

            const success = await storage.set(defaultData);
            if (success) {
              console.log('Default data initialized successfully');
            } else {
              console.error('Failed to initialize default data');
            }
          } else {
            console.log('Categories already exist, skipping default initialization');
          }
          resolve();
        } catch (error) {
          console.error('Error in initializeDefaultData callback:', error);
          reject(error);
        }
      });
    });
  } catch (error) {
    console.error('Error initializing default data:', error);
    throw error;
  }
};

// 自动初始化
initializeDefaultData(); 